package com.google.code.dnaep.jdo;

import java.util.Collection;
import java.util.Iterator;

import javax.jdo.FetchPlan;

import org.datanucleus.jdo.JDOExtent;

public class Extent<E> implements javax.jdo.Extent<E> {
	
	private final JDOExtent jdoExtent;
	private final boolean hasSubclasses;
    private javax.jdo.Query query;

	public Extent(JDOExtent jdoExtent) {
	    this(jdoExtent, true);
    }

	public Extent(JDOExtent jdoExtent, boolean hasSubclasses) {
	    this.jdoExtent = jdoExtent;
	    this.hasSubclasses = hasSubclasses;
    }

	@Override
	public Iterator<E> iterator() {
		ensureQuery();
	    return ((Collection)query.execute()).iterator();
    }

	@Override
	public boolean hasSubclasses() {
	    return hasSubclasses;
    }

	@Override
	public Class<E> getCandidateClass() {
	    return jdoExtent.getCandidateClass();
    }

	@Override
	public javax.jdo.PersistenceManager getPersistenceManager() {
	    return jdoExtent.getPersistenceManager();
    }

	@Override
	public void closeAll() {
		ensureQuery();
	    jdoExtent.closeAll();
	    query.closeAll();
    }

	@Override
	public void close(Iterator<E> it) {
		ensureQuery();
	    jdoExtent.close(it);
	    query.close(it);
	}

	@Override
	public FetchPlan getFetchPlan() {
	    return jdoExtent.getFetchPlan();
    }

	public JDOExtent getJdoExtent() {
    	return jdoExtent;
    } 
	
	private synchronized void ensureQuery() {
		if (query != null) {
			return;
		}
		query = getPersistenceManager().newQuery(this);
	}

}
